﻿#region Using Directives

    using System;
    using System.Linq;
    using System.Text;

    using Csla;
    using Csla.Data;
    using Csla.Server;
    using Csla.Reflection;

    using MarketPulse.BusinessLogic.Common;
    using MarketPulse.BusinessLogic.Common.Criteria;
    using MarketPulse.BusinessLogic.Private;
    using MarketPulse.BusinessLogic.Private.Criteria;

    using MarketPulse.DataAccess.DataContextObjects.Production;

#endregion

namespace MarketPulse.DataAccess.Factory
{
    /// <summary>
    /// Abstracts the data access for a Branch, BranchInfo, BranchAttribute, BranchAttributeList and BranchAttributeInfoList away from a Branch Business Object.
    /// </summary>
    public class BranchFactory : ObjectFactory
    {

        #region Member Variables

            /// <summary>
            /// Property that stores the name of the class.
            /// </summary>
            private static readonly Type mClass = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;

            /// <summary>
            /// Property that stores the log4net logger for this class.
            /// </summary>
            private static readonly log4net.ILog mLog = log4net.LogManager.GetLogger(mClass);

        #endregion

        #region Methods

            #region Create Methods

                /// <summary>
                /// Method used to create and return a new BranchAttribute object instance
                /// </summary>
                /// <returns>The newly created BranchAttribute object</returns>
                public BusinessLogic.Private.BranchAttribute CreateBranchAttribute()
                {
                    // Create a new instance of the object
                    var branchAttribute = (BusinessLogic.Private.BranchAttribute)MethodCaller.CreateInstance(typeof(BusinessLogic.Private.BranchAttribute));

                    branchAttribute.Obsolete = false;

                    // Mark it as a new oobject
                    MarkNew(branchAttribute);

                    // Mark the BranchAttribute as a child element
                    MarkAsChild(branchAttribute);

                    return branchAttribute;
                }

            #endregion

            #region Fetch Methods

                #region BranchInfo

                    /// <summary>
                    /// Method used to fetch a Read Only copy of an existing Branch from the database given a guid.
                    /// </summary>
                    /// <param name="criteria">The criteria object holding the Guid of the Branch to retrieve</param>
                    /// <returns>The Branch object retrieved from the database</returns>
                    public BusinessLogic.Common.BranchInfo FetchInfo(SingleCriteria<Guid> criteria)
                    {
                        try
                        {
                            using (var mgr = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                            {
                                // Create an instance to return
                                var branchInfo = (BusinessLogic.Common.BranchInfo)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchInfo));

                                // Fetch the data from the database based on the criteria
                                var selectResult = mgr.DataContext.UspBranchSelect(criteria.Value);

                                // Get the result
                                UspBranchSelectResult result = null;
                                try
                                {
                                    result = selectResult.Single();
                                }
                                catch (InvalidOperationException ioe)
                                {
                                    // Construct error message
                                    StringBuilder errorMessage = new StringBuilder();
                                    errorMessage.Append("Unable to locate exactly one Branch with Guid = [ ");
                                    errorMessage.Append(criteria.Value);
                                    errorMessage.Append(" ]");
                                    mLog.Error(errorMessage.ToString(), ioe);
                                    throw new DataAccessException(errorMessage.ToString());
                                }

                                // Common properties inherited from MarketPulseBase<Branch>
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.GUIDProperty, criteria.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.ObsoleteProperty, result.Obsolete.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertDateTimeProperty, result.InsertDateTime.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateDateTimeProperty, result.UpdateDateTime.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                // Other properties
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mCompanyGuidProperty, result.CompanyGUID.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAreaGuidProperty, result.AreaGUID.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBranchNameProperty, result.BranchName);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBuildingNameOrNumberProperty, result.BuildingNameOrNumber);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine1Property, result.AddressLine1);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine2Property, result.AddressLine2);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine3Property, result.AddressLine3);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine4Property, result.AddressLine4);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine5Property, result.AddressLine5);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mPostCodeProperty, result.PostCode);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mMemoProperty, result.Memo);

                                if (result.LegacyBranchID.HasValue)
                                {
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLegacyBranchIdProperty, result.LegacyBranchID.Value);
                                }
                                if (result.Latitude.HasValue)
                                {
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLatitudeProperty, result.Latitude.Value);
                                }
                                if (result.Longtitude.HasValue)
                                {
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLongtitudeProperty, result.Longtitude.Value);
                                }

                                // Make sure that CSLA knows this has changed since being instantiated
                                MarkOld(branchInfo);
                                // Set to being readonly (Info only)
                                SetIsReadOnly(branchInfo, true);

                                return branchInfo;
                            }
                        }
                        catch (DataAccessException dae)
                        {
                            mLog.Error(dae.ToString());
                            throw dae;
                        }
                        catch (Exception ex)
                        {
                            mLog.Error(ex.ToString());
                            throw ex;
                        }                
                    }


                    /// <summary>
                    /// Method used to fetch a Read Only copy of an existing Branch from the database given a Visitguid.
                    /// </summary>
                    /// <param name="criteria">The criteria object holding the Guid of the Visit for the branch to retrieve</param>
                    /// <returns>The Branch object retrieved from the database</returns>
                    public BusinessLogic.Common.BranchInfo FetchInfo(VisitGUIDCriteria criteria)
                    {
                        try
                        {
                            using (var mgr = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                            {
                                // Create an instance to return
                                var branchInfo = (BusinessLogic.Common.BranchInfo)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchInfo));

                                // Fetch the data from the database based on the criteria
                                var selectResult = mgr.DataContext.UspBranchSelectByVisitGUID(criteria.VisitGUID);

                                // Get the result
                                UspBranchSelectByVisitGUIDResult result;
                                try
                                {
                                    result = selectResult.FirstOrDefault();
                                }
                                catch (InvalidOperationException ioe)
                                {
                                    // Construct error message
                                    StringBuilder errorMessage = new StringBuilder();
                                    errorMessage.Append("Unable to locate exactly one Branch with Guid = [ ");
                                    errorMessage.Append(criteria.VisitGUID);
                                    errorMessage.Append(" ]");
                                    mLog.Error(errorMessage.ToString(), ioe);
                                    throw new DataAccessException(errorMessage.ToString());
                                }

                                // Common properties inherited from MarketPulseBase<Branch>
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.GUIDProperty, result.BranchGUID.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.ObsoleteProperty, result.Obsolete.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertDateTimeProperty, result.InsertDateTime.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateDateTimeProperty, result.UpdateDateTime.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                // Other properties
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mCompanyGuidProperty, result.CompanyGUID.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAreaGuidProperty, result.AreaGUID.Value);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBranchNameProperty, result.BranchName);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBuildingNameOrNumberProperty, result.BuildingNameOrNumber);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine1Property, result.AddressLine1);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine2Property, result.AddressLine2);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine3Property, result.AddressLine3);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine4Property, result.AddressLine4);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine5Property, result.AddressLine5);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mPostCodeProperty, result.PostCode);
                                LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mMemoProperty, result.Memo);

                                if (result.LegacyBranchID.HasValue)
                                {
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLegacyBranchIdProperty, result.LegacyBranchID.Value);
                                }
                                if (result.Latitude.HasValue)
                                {
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLatitudeProperty, result.Latitude.Value);
                                }
                                if (result.Longtitude.HasValue)
                                {
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLongtitudeProperty, result.Longtitude.Value);
                                }

                                // Make sure that CSLA knows this has changed since being instantiated
                                MarkOld(branchInfo);
                                // Set to being readonly (Info only)
                                SetIsReadOnly(branchInfo, true);

                                return branchInfo;
                            }
                        }
                        catch (DataAccessException dae)
                        {
                            mLog.Error(dae.ToString());
                            throw dae;
                        }
                        catch (Exception ex)
                        {
                            mLog.Error(ex.ToString());
                            throw ex;
                        }  
                    }

                #endregion      

                #region BranchAttributeList

                    /// <summary>
                    /// Method used to fetch a list of BranchAttributes associated with this Branch from 
                    /// the database given a the Branch GUID
                    /// </summary>
                    /// <param name="criteria">The criteria object holding the Guid of the Branch to retrieve the list for</param>
                    /// <returns>The collection of BranchAttributes fetched from the database</returns>
                    public BusinessLogic.Private.BranchAttributeList FetchBranchAttributeList(SingleCriteria<Guid> criteria)
                    {
                        try
                        {
                            using (var manager = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                            {
                                var branchAttributeList = (BusinessLogic.Private.BranchAttributeList)MethodCaller.CreateInstance(typeof(BusinessLogic.Private.BranchAttributeList));

                                var selectResult = manager.DataContext.UspBranchAttributeSelectByBranchGUID(criteria.Value);

                                foreach (UspBranchAttributeSelectByBranchGUIDResult result in selectResult)
                                {
                                    BusinessLogic.Private.BranchAttribute branchAttribute = (BusinessLogic.Private.BranchAttribute)MethodCaller.CreateInstance(typeof(BusinessLogic.Private.BranchAttribute));

                                    // Common properties inherited from MarketPulseBase<BranchAttribute>
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.GUIDProperty, result.BranchAttributeGUID);
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.ObsoleteProperty, result.Obsolete.Value);
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.InsertDateTimeProperty, result.InsertDateTime.Value);
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.UpdateDateTimeProperty, result.UpdateDateTime.Value);
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                    // Other properties                    
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.BranchGUIDProperty, criteria.Value);
                                    LoadProperty(branchAttribute, BusinessLogic.Private.BranchAttribute.BranchAttributeTypeGUIDProperty, result.BranchAttributeTypeGUID);


                                    // Mark the Visit Event as a child element
                                    MarkAsChild(branchAttribute);

                                    // Make sure that CSLA knows this has changed since being instantiated
                                    MarkOld(branchAttribute);

                                    branchAttributeList.RaiseListChangedEvents = false;
                                    // Add the item to the list
                                    branchAttributeList.Add(branchAttribute);
                                    branchAttributeList.RaiseListChangedEvents = true;
                                }

                                // Make sure that CSLA knows this has changed since being instantiated
                                MarkOld(branchAttributeList);

                                return branchAttributeList;
                            }
                        }
                        catch (DataAccessException dae)
                        {
                            mLog.Error(dae.ToString());
                            throw dae;
                        }
                        catch (Exception ex)
                        {
                            mLog.Error(ex.ToString());
                            throw ex;
                        }  
                    }

                #endregion

                #region BranchAttributeInfoList

                    /// <summary>
                    /// Method used to fetch a (Read Only) list of BranchAttributes associated with this Branch from 
                    /// the database given the Branch GUID
                    /// </summary>
                    /// <param name="criteria">The criteria object holding the Guid of the Branch to retrieve the list for</param>
                    /// <returns>The (read only) collection of BranchAttributes fetched from the database</returns>
                    public BusinessLogic.Common.BranchAttributeInfoList FetchAttributeInfoList(SingleCriteria<Guid> criteria)
                    {
                        using (var manager = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                        {
                            var branchAttributeInfoList = (BusinessLogic.Common.BranchAttributeInfoList)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchAttributeInfoList));

                            var selectResult = manager.DataContext.UspBranchAttributeSelectByBranchGUID(criteria.Value);

                            // branchAttributeInfoList is a read-only collection,
                            // so typically, when the data access is implemented in
                            // DataPortal_Fetch within the business object, the
                            // private IsReadOnly property must be set false in order to 
                            // populate the collection.  Here, within a factory 
                            // , it isn't visible so one must resort to calling the 
                            // SetIsReadOnly method provided by our parent, ObjectFactory.
                            SetIsReadOnly(branchAttributeInfoList, false);
                            foreach (UspBranchAttributeSelectByBranchGUIDResult result in selectResult)
                            {
                                BusinessLogic.Common.BranchAttributeInfo branchAttributeInfo = (BusinessLogic.Common.BranchAttributeInfo)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchAttributeInfo));

                                // Common properties inherited from MarketPulseBase<BranchAttributeInfo>
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.GUIDProperty, result.BranchAttributeGUID);
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.ObsoleteProperty, result.Obsolete.Value);
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.InsertDateTimeProperty, result.InsertDateTime.Value);
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.UpdateDateTimeProperty, result.UpdateDateTime.Value);
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                // Other properties                    
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.BranchGUIDProperty, criteria.Value);
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.BranchAttributeTypeGUIDProperty, result.BranchAttributeTypeGUID);
                                LoadProperty(branchAttributeInfo, BusinessLogic.Common.BranchAttributeInfo.BranchAttributeNameProperty, result.BranchAttributeTypeName);

                                // Mark the BranchInfo as a child element
                                MarkAsChild(branchAttributeInfo);

                                // Make sure that CSLA knows this has changed since being instantiated
                                MarkOld(branchAttributeInfo);

                                // Add the item to the list
                                branchAttributeInfoList.Add(branchAttributeInfo);
                            }
                            SetIsReadOnly(branchAttributeInfoList, true);

                            // Make sure that CSLA knows this has changed since being instantiated
                            MarkOld(branchAttributeInfoList);

                            return branchAttributeInfoList;
                        }
                    }

                #endregion

                #region BranchInfoList

                    /// <summary>
                    /// Method used to fetch a read only list of read only Branch objects from the database based on the ProfileGUID and CompanyGUID criteria supplied             
                    /// </summary>
                    /// <param name="criteria">The criteria object holding the ProfileGUID and CompanyGUID used to retrieve the list</param>
                    /// <returns>A read only list of read only Branch objects retrieved from the database</returns>
                    public BusinessLogic.Common.BranchInfoList FetchInfoList(SingleCriteria<Guid> criteria)
                    {
                        try
                        {
                            using (var manager = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                            {
                                // Create an instance to return
                                var branchInfoList = (BusinessLogic.Common.BranchInfoList)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchInfoList));

                                // Fetch the data from the database based on the criteria
                                var selectResult = manager.DataContext.UspBranchSelectByClientGUID(criteria.Value);

                                // BranchInfoList is a read-only collection,
                                // so typically, when the data access is implemented in
                                // DataPortal_Fetch within the business object, the
                                // private IsReadOnly property must be set false in order to 
                                // populate the collection.  Here, within a factory 
                                // , it isn't visible so one must resort to calling the 
                                // SetIsReadOnly method provided by our parent, ObjectFactory.
                                SetIsReadOnly(branchInfoList, false);
                                foreach (UspBranchSelectByClientGUIDResult result in selectResult)
                                {
                                    BusinessLogic.Common.BranchInfo branchInfo = (BusinessLogic.Common.BranchInfo)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchInfo));

                                    // Common properties inherited from MarketPulseBase<Branch>
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.GUIDProperty, result.BranchGUID);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.ObsoleteProperty, result.Obsolete.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                    // Other properties
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mCompanyGuidProperty, result.CompanyGUID.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAreaGuidProperty, result.AreaGUID.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBranchNameProperty, result.BranchName);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBuildingNameOrNumberProperty, result.BuildingNameOrNumber);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine1Property, result.AddressLine1);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine2Property, result.AddressLine2);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine3Property, result.AddressLine3);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine4Property, result.AddressLine4);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine5Property, result.AddressLine5);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mPostCodeProperty, result.PostCode);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mMemoProperty, result.Memo);

                                    if (result.LegacyBranchID.HasValue)
                                    {
                                        LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLegacyBranchIdProperty, result.LegacyBranchID.Value);
                                    }

                                    if (result.Latitude.HasValue)
                                    {
                                        LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLatitudeProperty, result.Latitude.Value);
                                    }

                                    if (result.Longtitude.HasValue)
                                    {
                                        LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLongtitudeProperty, result.Longtitude.Value);
                                    }
                                    //CheckRules(branchInfo);

                                    // Make sure that CSLA knows this has changed since being instantiated
                                    MarkOld(branchInfo);

                                    // Add the item to the list
                                    branchInfoList.Add(branchInfo);
                                }
                                SetIsReadOnly(branchInfoList, true);

                                // Make sure that CSLA knows this has changed since being instantiated
                                MarkOld(branchInfoList);

                                return branchInfoList;
                            }
                        }
                        catch (DataAccessException dae)
                        {
                            mLog.Error(dae.ToString());
                            throw dae;
                        }
                        catch (Exception ex)
                        {
                            mLog.Error(ex.ToString());
                            throw ex;
                        }  
                    }

                    /// <summary>
                    /// Method used to fetch a read only list of read only Branch objects from the database based on the ProfileGUID, CompanyGUID and date range criteria supplied
                    /// </summary>
                    /// <param name="criteria">The criteria object holding the ProfileGUID, CompanyGUID and date range used to retrieve the list</param>
                    /// <returns>A read only list of read only Branch objects retrieved from the database</returns>
                    public BusinessLogic.Common.BranchInfoList FetchInfoList(ClientGUIDAndProfileGUIDAndDateRangeCriteria criteria)
                    {
                        try
                        {
                            using (var manager = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                            {
                                // Create an instance to return
                                var branchInfoList = (BusinessLogic.Common.BranchInfoList)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchInfoList));

                                // Fetch the data from the database based on the criteria
                                var selectResult = manager.DataContext.UspBranchSelectByClientGUIDAndProfileGUIDAndDateRange(criteria.ClientGUID, criteria.ProfileGUID, criteria.StartDateTime, criteria.EndDateTime, true);

                                // BranchInfoList is a read-only collection,
                                // so typically, when the data access is implemented in
                                // DataPortal_Fetch within the business object, the
                                // private IsReadOnly property must be set false in order to 
                                // populate the collection.  Here, within a factory 
                                // , it isn't visible so one must resort to calling the 
                                // SetIsReadOnly method provided by our parent, ObjectFactory.
                                SetIsReadOnly(branchInfoList, false);
                                foreach (UspBranchSelectByClientGUIDAndProfileGUIDAndDateRangeResult result in selectResult)
                                {
                                    BusinessLogic.Common.BranchInfo branchInfo = (BusinessLogic.Common.BranchInfo)MethodCaller.CreateInstance(typeof(BusinessLogic.Common.BranchInfo));

                                    // Common properties inherited from MarketPulseBase<Branch>
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.GUIDProperty, result.BranchGUID);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.ObsoleteProperty, result.Obsolete.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                    // Other properties
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mCompanyGuidProperty, result.CompanyGUID.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAreaGuidProperty, result.AreaGUID.Value);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBranchNameProperty, result.BranchName);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mBuildingNameOrNumberProperty, result.BuildingNameOrNumber);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine1Property, result.AddressLine1);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine2Property, result.AddressLine2);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine3Property, result.AddressLine3);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine4Property, result.AddressLine4);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mAddressLine5Property, result.AddressLine5);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mPostCodeProperty, result.PostCode);
                                    LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mMemoProperty, result.Memo);

                                    if (result.LegacyBranchID.HasValue)
                                    {
                                        LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLegacyBranchIdProperty, result.LegacyBranchID.Value);
                                    }

                                    if (result.Latitude.HasValue)
                                    {
                                        LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLatitudeProperty, result.Latitude.Value);
                                    }

                                    if (result.Longtitude.HasValue)
                                    {
                                        LoadProperty(branchInfo, BusinessLogic.Common.BranchInfo.mLongtitudeProperty, result.Longtitude.Value);
                                    }
                                    //CheckRules(branchInfo);

                                    // Make sure that CSLA knows this has changed since being instantiated
                                    MarkOld(branchInfo);

                                    // Add the item to the list
                                    branchInfoList.Add(branchInfo);
                                }
                                SetIsReadOnly(branchInfoList, true);

                                // Make sure that CSLA knows this has changed since being instantiated
                                MarkOld(branchInfoList);

                                return branchInfoList;
                            }
                        }
                        catch (DataAccessException dae)
                        {
                            mLog.Error(dae.ToString());
                            throw dae;
                        }
                        catch (Exception ex)
                        {
                            mLog.Error(ex.ToString());
                            throw ex;
                        }
                    }

                #endregion

            #endregion

        #endregion
    }
}
